package com.situ.mall.service.impl;

import cn.hutool.db.sql.Order;
import cn.hutool.db.sql.Query;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.situ.mall.constant.MqConstant;
import com.situ.mall.constant.OrderStatusConstant;
import com.situ.mall.mapper.CartMapper;
import com.situ.mall.mapper.OrderItemMapper;
import com.situ.mall.pojo.dto.OrderDTO;
import com.situ.mall.pojo.entity.OrderItem;
import com.situ.mall.pojo.entity.Orders;
import com.situ.mall.mapper.OrdersMapper;
import com.situ.mall.pojo.query.OrderQuery;
import com.situ.mall.pojo.vo.CartVO;
import com.situ.mall.pojo.vo.OrderVO;
import com.situ.mall.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.situ.mall.util.MultiDelayMessage;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Gao
 * @since 2025-10-15
 */
@Service
@Transactional
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    int num = 2;

    //@Transactional
    //@Transactional(propagation = Propagation.SUPPORTS)
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
    @Override
    public Long add(OrderDTO orderDTO) {
        List<CartVO> cartVOList = cartMapper.selectByIds(orderDTO.getCartIds());
        Orders orders = new Orders();
        orders.setShippingId(orderDTO.getShippingId());
        orders.setUserId(orderDTO.getUserId());

        BigDecimal payment = cartVOList.stream()
                .map(cartVO -> cartVO.getProductPrice().multiply(BigDecimal.valueOf(cartVO.getCount())))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        orders.setPayment(payment);
        ordersMapper.insert(orders);


        for (CartVO cartVO : cartVOList) {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderNo(orders.getOrderNo());
            orderItem.setUserId(orderDTO.getUserId());
            orderItem.setProductId(cartVO.getProductId());
            orderItem.setProductName(cartVO.getProductName());
            orderItem.setProductImage(cartVO.getProductImage());
            orderItem.setProductPrice(cartVO.getProductPrice());
            orderItem.setCount(cartVO.getCount());

            //计算当前商品的数量*价格
            BigDecimal productPrice = cartVO.getProductPrice();
            BigDecimal count = BigDecimal.valueOf(cartVO.getCount());
            BigDecimal totalPrice = productPrice.multiply(count);
            orderItem.setTotalPrice(totalPrice);
            orderItemMapper.insert(orderItem);

            //删除购物车里面对应的商品
            cartMapper.deleteById(cartVO.getId());
        }

        //发送延时消息
        MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orders.getOrderNo(),  10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L);
        Long delay = msg.removeNextDelay();
        rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE, MqConstant.DELAY_ORDER_ROUTING_KEY, msg, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setDelay(Math.toIntExact(delay));
                return message;
            }
        });

        return orders.getOrderNo();
    }

    @Override
    public void pay(Long orderNo) {
        UpdateWrapper<Orders> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("order_no", orderNo);
        updateWrapper.set("status", OrderStatusConstant.PAYED);
        updateWrapper.set("payment_time", new Date());
        ordersMapper.update(updateWrapper);
    }

    @Override
    public List<OrderVO> selectListByUser(Integer userId) {
        return ordersMapper.selectListByUser(userId);
    }

    @Override
    public IPage<Orders> list(OrderQuery orderQuery) {
        IPage<Orders> page  = new Page<>(orderQuery.getPage(), orderQuery.getLimit());
        return ordersMapper.list(page, orderQuery);
    }

    @Override
    public List<OrderItem> selectOrderItemByOrderNo(Long orderNo) {
        QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        return orderItemMapper.selectList(queryWrapper);
    }

    @Override
    public void cancelOrder(Long orderNo) {
        UpdateWrapper<Orders> wrapper = new UpdateWrapper<>();
        wrapper.set("status", 0).eq("order_no", orderNo);
        ordersMapper.update(wrapper);
    }
}
